Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建Web抓取规则_Python_Mysql_Database_Parsing_Web Scraping - Fatal编程技术网

Python 创建Web抓取规则

Python 创建Web抓取规则,python,mysql,database,parsing,web-scraping,Python,Mysql,Database,Parsing,Web Scraping,我在这一页: 我想深入每一项,了解开发者和类型,但我的代码似乎不起作用 例如,我想进入这个页面: 然后离开它,继续执行其余的操作,并将其添加到数据库中。我可以在我的代码中更改什么以使其工作?现在数据库是针对开发人员的,类型是空的,但它得到了其余的数据,所以它就像从未进入parse_游戏一样 我还在parseGame中添加了print语句,但它们都没有打印出来 from scrapy.spider import BaseSpider from scrapy.selector import Sele

我在这一页:

我想深入每一项,了解开发者和类型,但我的代码似乎不起作用

例如,我想进入这个页面:

然后离开它,继续执行其余的操作,并将其添加到数据库中。我可以在我的代码中更改什么以使其工作?现在数据库是针对开发人员的,类型是空的,但它得到了其余的数据,所以它就像从未进入parse_游戏一样

我还在parseGame中添加了print语句,但它们都没有打印出来

from scrapy.spider import BaseSpider
from scrapy.selector import Selector
from scrapy.http import Request
from scrapy.selector import HtmlXPathSelector
from metacritic.items import MetacriticItem
import MySQLdb
import re
from string import lowercase

class MetacriticSpider(BaseSpider):
def start_requests(self):
    #iterate through ps4 pages
    for c in lowercase:
        for i in range(self.max_id):
            yield Request('http://www.metacritic.com/browse/games/title/ps4/{0}?page={1}'.format(c, i), callback = self.parseps4)

    #gets the developer and genre of a game
def parseGame(self, response):

    print("Here")

    item = response.meta['item']

    db1 = MySQLdb.connect("localhost", "root", "andy", "metacritic")
    cursor = db1.cursor()
    hxs = HtmlXPathSelector(response)   
    sites = hxs.select('//div[@class="product_wrap"]')
    items = []

    item['dev'] = site.xpath('.//span[contains(@class, "summary_detail developer")]/span[1]/text()').extract()
    item['genre'] = site.xpath('.//span[contains(@class, "summary_detail product_genre")]/span[1]/text()').extract()    

    cursor.execute("INSERT INTO ps4 (dev, genre) VALUES (%s,%s)",[item['dev'][0],item['genre'][0]])
    items.append(item)

    print item['dev']
    print item['genre']

def parseps4(self, response):
    #some local variables
    db1 = MySQLdb.connect("localhost", "root", "andy", "metacritic")
    cursor = db1.cursor()
    hxs = HtmlXPathSelector(response)   
    sites = hxs.select('//div[@class="product_wrap"]')
    items = []

    #iterates through each site
    for site in sites:
        with db1:
            item = MetacriticItem()

            #sets the item
            item['title'] = site.xpath('.//div[contains(@class, "basic_stat product_title")]/a/text()').extract()
            item['cscore'] = site.xpath('.//div[contains(@class, "basic_stat product_score brief_metascore")]/div[1]/text()').extract() 
            item['uscore'] = site.xpath('.//div/ul/li/span[contains(@class, "data textscore")]/text()').extract()
            item['release'] = site.xpath('.//li[contains(@class, "stat release_date full_release_date")]/span[2]/text()').extract()

            #some processing to check if there is a score attached, if there is, it adds it to the database
            if ("tbd" in item['cscore'][0] and "tbd" not in item['uscore'][0]) or ("tbd" not in item['cscore'][0] and "tbd" in item['uscore'][0]) or ("tbd" not in item['cscore'][0] and "tbd" not in item['uscore'][0]):
                cursor.execute("INSERT INTO ps4 (title, criticalscore, userscore, releasedate) VALUES (%s,%s,%s, %s)",[(' '.join(item['title'][0].split())).replace("(PS4)","",1),item['cscore'][0],item['uscore'][0],item['release'][0]])
                items.append(item)

            itemLink = site.xpath('.//div[contains(@class, "basic_stat product_title")]/a/@href' ).extract()

            req = Request('http://www.metacritic.com' +  itemLink[0], callback = self.parseGame)
            req.meta['item'] = item

代码中的几个问题:

  • 元参数应包含字典
    {'item':item}
  • HtmlXPathSelector
    已被弃用-请改用
    Selector
  • 我认为您不应该在spider中插入mysql,而是应该使用数据库管道:
  • 您需要获取
    extract()
    call的第一项,并在其上执行
    strip()
    (这将有助于在字段中包含字符串,而不是列表,并且没有前导和尾随空格和换行符)
下面是没有相关调用的代码:

from string import lowercase

from scrapy.item import Field, Item
from scrapy.spider import BaseSpider
from scrapy.http import Request
from scrapy.selector import HtmlXPathSelector, Selector

from metacritic.items import MetacriticItem


class MetacriticSpider(BaseSpider):
    name = 'metacritic'
    allowed_domains = ['metacritic.com']

    max_id = 1 # your max_id value goes here!!!

    def start_requests(self):
        for c in lowercase:
            for i in range(self.max_id):
                yield Request('http://www.metacritic.com/browse/games/title/ps4/{0}?page={1}'.format(c, i), callback=self.parseps4)

    def parseGame(self, response):
        item = response.meta['item']
        hxs = HtmlXPathSelector(response)
        site = hxs.select('//div[@class="product_wrap"]')

        # get additional data!!!

        yield item

    def parseps4(self, response):
        hxs = Selector(response)
        sites = hxs.select('//div[@class="product_wrap"]')
        for site in sites:
            item = MetacriticItem()
            item['title'] = site.xpath('.//div[contains(@class, "basic_stat product_title")]/a/text()').extract()[0].strip()
            item['cscore'] = site.xpath('.//div[contains(@class, "basic_stat product_score brief_metascore")]/div[1]/text()').extract()[0].strip()
            item['uscore'] = site.xpath('.//div/ul/li/span[contains(@class, "data textscore")]/text()').extract()[0].strip()
            item['release'] = site.xpath('.//li[contains(@class, "stat release_date full_release_date")]/span[2]/text()').extract()[0].strip()

            link = site.xpath('.//div[contains(@class, "basic_stat product_title")]/a/@href').extract()[0]
            yield Request('http://www.metacritic.com/' + link, meta={'item': item}, callback=self.parseGame)
它对我很有用-我在控制台上看到了
parseGame()
中生成的项目

确保它首先生成项目,然后查看
注释-相应地填写这些行


之后,如果您在控制台上看到项目,请尝试创建一个数据库管道来将项目写入mysql。

看起来您忘记将
yield
放在
请求之前了(
)http://www.metacritic.com“+itemLink[0],callback=self.parseGame)
@alecxe我尝试了这个,但不幸的是它没有工作。还有其他想法吗?至少还有一个问题。在
parseGame
中,未定义
项。您需要将
项目
parseps4
传递到
meta
中的
parseGame
:请参见。您在
parseps4
末尾缺少
yield req
。您是否可以添加spider的类定义并导入语句,以便我可以在本地进行尝试和调试?@AndyOHart hm,如果您将打印内容放入
start\u请求
parseps4
,您看到了吗?@AndyOHart好的,谢谢,再来一次测试。在生成请求之前,将
print(link)
放进去-它看起来像什么?你能在浏览器中打开这个url吗?我已经开始工作了,我只需要更改hxs。再次感谢所有的帮助人员:)@AndyOHart我想你在访问它之前没有设置
项['dev']
。@AndyOHart好吧,就我所知,顺序是
开始请求
->
parsePS4
->
parseGame