一、翻页的方式复习
观察网页结构通过获取下一页的href的值在进行适当的url拼接
if response.xpath('//a[text()="Next »"]/@href'):
next_page = response.xpath('//a[text()="Next»"]/@href').extract()[0]
print('next_page',next_page)
next_page = response.urljoin(next_page)
# print(next_page)
yield Request(next_page, callback=self.parse_second, meta={'item': item})
二、观察querystring然后凭借不同页不同的querystring去访问
for next_page in range(0,166):
next_page = 'http://tochka3evlj3sxdv.com/?page={}&city=0&category=0&sortby=popularity&account=all&shipping-to=&shipping-from=&query='.format(next_page)
next_page = response.urljoin(next_page)
yield Request(next_page, callback=self.parse_sencond,meta={'item': item})
三、post来说,要通过表单去实现翻页
u = response.url
cat = re.findall(r'&cat=([\s|\S]+)', u)[0]
print(cat) page = response.xpath('//button[@class="btn btn-primary"][last()]/@value').extract()[0]
print(page)
for i in range(1, int(page)):
print(i)
formdata = {
'title':'',
'search':'1',
'searchcat':'1',
'dator':'9Ac3^nYrdUjEUa8LRdV7RVHchwj6pC(u',
'type':'all',
'payment':'all',
'priceMin':'',
'priceMax':'',
'shipsfrom':'all',
'shipsto':'all',
'field':'all',
'order':'all',
'displayname':'',
'cat':cat,
'page':str(i) }
yield FormRequest(u, formdata=formdata,callback=self.parse_third, meta={'item': item})
四、selenium实现翻页
res = etree.HTML(self.browser.page_source)
page = res.xpath('//div[@id="page"]/a/@href')
for u in page:
next_url = 'https://www.baidu.com' + u
print(next_url)
self.browser.get(next_url)
二、scrapy翻页
主要是在spider,py的parse方法中搞
翻页要判断是不是最后一段,有的网站即使是最后一页,下一页也会有href属性,所以要取出href属性进行if判断
next_url=response.xpath(...../@href).extract_first()
if next_url="xx":
url=response.urljoin(BASE_URL+next_url)
yield scrapy.Request(url,callback=self.parse)##不同页相同的回调执行,类似递归,如果想采用不同的回调函数,可以在下方自定义
def parse1(self,response)
else: ....
三、useragent配置
settings.py 中有关于useragent的注释,取消后可以自己改相应useragent
四、不同解析函数的参数传递
关键字meta
def parse(self,response):
yield item
#item为要传的参数
yield scrapy.Request(url,callback=self.parse1,meta={"item",item})
#还有一个参数dont_filter是scrapy的去重功能,默认请求过的url不会再被请求,所以如果要继续请求还需要设置为True,比如同url在不同时间效果不一样比如百度贴吧这样的,要定时去重新访问的,要搞到true
def parse1(self,resoponse): response.meta['item']#获取到了item
五、items.py的使用
items.py的使用
import scrapy
class TencentItem(scrapy.Item):
# define the fields for your item here like:
title=scrapy.Field()
name=scrapy.Field()##为要爬取的字段占位
pass
在items定义完了以后,在spider中引入对应类,然后创建一个items对象,这个items对象就是类似一个字典,可以采用字典操作给入键,然后值则是要爬取的内容。
采用以上方式由于item已经不是一个字典了,所以要使用mongodb插入字典类型数据则需要insert(dict(item))
而且在items中可以定义多个类,在pipeline中引入后 通过if isinstance判断传来的item是属于哪个类,进而判断是那个爬虫对应的item字段,插入到不同的数据库
Final
请务必在meta传参时对item进行深拷贝
meta={“item”:deepcopy(itrm)} 在多进程的情况下,后面爬的item的某些key在前面使用时会被修改,因为我们传参都是传引用,所以后面的item值也会变, print获取的是一瞬间的所有item值,很容易错拼的
案例
# -*- coding: utf-8 -*-
import request
import scrapy
from ..items import InformationItem,GameItem
from copy import deepcopy
class ScrapygameSpider(scrapy.Spider):
name = 'scrapygame'
allowed_domains = ['4399.com']
start_urls = ['http://4399.com/']
def parse(self, response):
BASE_URL = 'http://4399.com'
lilist=response.xpath("//*[@id='skinbody']/div[10]/div[1]/div[1]/ul/li")
for li in lilist:
item1=GameItem()
item1["gamename"]=li.xpath("./a/text()").extract_first()
item1["next_page"]=li.xpath("./a/@href").extract_first()
yield item1
new_url=BASE_URL+item1["next_page"]
yield scrapy.Request(new_url,callback=self.parse_date,meta={"gamename":deepcopy(item1["gamename"])})
def parse_date(self,response):
item2 = InformationItem()
gamename=response.meta["gamename"]
date=response.css("div .cls::text").extract_first()
yield item2
Comments NOTHING