商业爬虫
Day1
图书推荐
图解HTTP,日本人写的
爬虫用处
诸葛
工商大数据
分类
通用爬虫
聚焦爬虫
https://www.jd.com/robots.txt
Day2
User-Agent池
Ip代理池
Day4
一个用户在不同的地方,不同的浏览器不停的登录,很有可能被封。面试遇到过。
解决方法:多个账号。多个IP统一并发
Day5
proxies
ssl
import requests headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0', } #1 代理IP 字典形式 #2 SSL认证 #HTTPS,是有第三方CA证书认证,但是12306 ,虽然是http是,但他不是CA证书,他是自己颁发的证书,解决方法是 #告诉web忽略证书访问,用到的参数是verify #3 GET请求 传参 query POST请求传参 formdata free_proxy = {'HTTP':'222.189.246.94:9999'} login_url = 'https://www.12306.cn/index/' r = requests.get(url=login_url,headers=headers,verify=False,proxies=free_proxy) f = open('day5_1.html','w',encoding='ISO-8859-1') f.write(r.text) f.close()
day 6
正则
re.S re.I
xpath
知道这几点就够用了
''' / 根节点 // 跨节点 定位精确的标签 //a[@属性='属性值'] 获取标签包裹的内容 /text() 获取标签的属性值 /a[@id='xx']/@href xpath返回的是列表 '''
''' //li[5] li 是平级标签 ok //a[3] 如果a 不是平级标签,那下标取值的方法不好使 '''
''' http://bbs.talkop.com/ 抓取海贼王论坛 收获(都很牛逼) 1 发现用类写爬虫 比用函数写爬虫爽一些,有些参数不用一直传,都在__init__中,在这里就是self.data_list。 2 json 终于意识到json的价值了,把列表类型转换成json类型,保存在文件中,可以从文件中copy出来,有转化json类型的网站,直接转化下,就可以看到其中的数据了 3 etree的使用,参数是bytes类型 ''' import requests import json from lxml import etree class TalkopSpider(object): def __init__(self): self.url = 'http://bbs.talkop.com/forum-fenxi-{}.html' self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0', } self.data_list = [] def get_response(self,url): ''' 发请求,获取网页内容 :param url: :return: ''' response = requests.get(url=url,headers=self.headers) return response.content def parse_data(self,data): ''' 接收bytes类型页面值,解析之,获取需要提取的数据, :param data: :return: ''' # data是bytes类型 # 转类型 x_data = etree.HTML(data) titles = x_data.xpath("//a[@class='s xst']/text()") urls = x_data.xpath("//a[@class='s xst']/@href") # 用这种方法,实现title,url一一对应。 for index,title in enumerate(titles): news = {} news[title] = urls[index] self.data_list.append(news) def save_data(self): ''' 将列表类型转换为json类型 :param data: :return: ''' j_data = json.dumps(self.data_list) with open('day6.json','w') as f: f.write(j_data) def run(self): for i in range(1,10): url = self.url.format(i) data = self.get_response(url) self.parse_data(data) self.save_data() TalkopSpider().run()
day7
模糊匹配
//div[contain(@class,'xx')]
beautifulsoup的使用
soup.find_all(name='a',class_='xx') soup.find_all(name='a',attrs={'class':'xx'}) 上面两个等价的
import requests from bs4 import BeautifulSoup from lxml import etree import json class BtcSpider(object): def __init__(self): self.url = 'http://8btc.com/forum-61-{}.html' self.headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"} # 保存列表页的数据 self.data_list = [] self.data_detail = [] # 1.发请求 def get_response(self, url): response = requests.get(url, headers=self.headers) data = response.content return data # 2.解析数据list def parse_list_data(self, data): # 1.转类型 BeautifulSoup可以接收bytes类型!!!!!!!!!! soup = BeautifulSoup(data, 'lxml') # 2.解析内容 取出 所有的类选择器的 A #这里拿到一直tag,就可以把tag包含的文本值,和tag对应的href一并取到!!!!!!!!!! title_list = soup.select('.xst') for title in title_list: list_dict_data = {} list_dict_data['title'] = title.get_text() list_dict_data['detail_url'] = title.get('href') self.data_list.append(list_dict_data) # 3.解析数据详情页 def parse_detail_data(self, data): html_data = BeautifulSoup(data, 'lxml') # 取出问题--list[1][0] question = html_data.select('#thread_subject')[0].get_text() print(question) answer_list = html_data.select('.t_f') for answer in answer_list: answer_list = [] answer_list.append(answer.get_text()) detail_data = { "question": question, "answer": answer_list } self.data_detail.append(detail_data) # 3.保存数据,多写了一个参数,作为文件名!!!!!更灵活 def save_data(self, data, file_path): data_str = json.dumps(data) with open(file_path, 'w') as f: f.write(data_str) def start(self): # 列表页的请求 for i in range(1, 2): url = self.url.format(1) data = self.get_response(url) self.parse_list_data(data) self.save_data(self.data_list, "04list.json") # 发送详情页的请求 for data in self.data_list: detail_url = data['detail_url'] detail_data = self.get_response(detail_url) # 解析详情页的数据 self.parse_detail_data(detail_data) self.save_data(self.data_detail, 'detail.json') BtcSpider().start() """ html_data = etree.HTML(data) result_list = html_data.xpath('//div[contains(@id,"stickthread")]') result_list = html_data.xpath('//head/following-sibling::*[1]') print(len(result_list)) print(result_list) """
day8
json dumps/dump/loads/load
在涉及到文件写入,读取,dump load 特别方便,省了中间一步。
import json data_list = [{'name':'左国梁','age':'23'},{'name':'张先','age':'32'}] # 方法 1 ,涉及文件读写,多了一步 转类型,把列表转换为json类型 ,比较繁琐 # j_data = json.dumps(data_list) # # with open('a.josn','w') as f: # f.write(j_data) # 方法 2 不需要单独把data_list,转为json json.dump(data_list,open('b.json','w'))
跨节点的使用
可以这样用,获取h2标签下所有的文本值
//h2[@class='niubi']//text()
day9
mongodb的安装使用--增删改查
https://www.cnblogs.com/linhaifeng/articles/8273498.html
增 insert
删 delete
改update $set
查 find()